﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Example.Application;
using System.Security.Principal;
using Ninject;
using Ninject.Planning.Bindings.Resolvers;
using Ninject.Planning.Bindings;
using Ninject.Activation.Strategies;
using Ninject.Activation;
using Example.Application.Account;
using Applay;
using Example.Persistence;

namespace Example.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var kernel = CreateKernel();

            var wrapper = kernel.Get<Wrapper>();

            var accountService = kernel.Get<AccountService>();

            using (var validationScope = wrapper.BeginValidation(new ConsoleValidationState()))
            {
              var registerModel = new RegisterModel
              {
                  Email = "lennart_schlegge@msn.com",
                  Password = "123",
                  PasswordConfirmation = "12"
              };

              accountService.Register(registerModel);
            }

            using (var validationScope = wrapper.BeginValidation(new ConsoleValidationState()))
            {
              var logInModel = new LogInModel
              {
                  Email = "lennart_schlegge@msn.com",
                  Password = "123"
              };

              if (accountService.LogIn(logInModel))
              {
                  System.Console.WriteLine("Logged in.");
              }
            }
            
            System.Console.ReadKey();
        }

        public class ConsoleValidationState : IValidationState
        {
            public ConsoleValidationState()
            {
                this.IsValid = true;
            }

            public void AddError(string message, params string[] keys)
            {
                this.IsValid = false;

                System.Console.WriteLine("Error: " + message);
            }

            public bool IsValid { get; private set; }
        }

        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();

            var wrapper = new Wrapper();
            wrapper.EnableAuthorization(() =>
            {
                var identity = new GenericIdentity("Lennart");
                return new GenericPrincipal(identity, new string[] { "Administrator"});
            });


            // components
            WrappedActionvationStrategy.Wrapper = wrapper;
            kernel.Components.Add<IActivationStrategy, WrappedActionvationStrategy>();

            // bindings
            kernel.Bind<Wrapper>().ToConstant(wrapper);

            kernel.Bind<IEntities>().To<Entities>();
            kernel.Bind<AccountService>().ToSelf().InSingletonScope();

            return kernel;
        }

    }

    public class WrappedActionvationStrategy : ActivationStrategy
    {
        public static Wrapper Wrapper;

        public override void Activate(IContext context, InstanceReference reference)
        {
            if(typeof(Service).IsAssignableFrom(reference.Instance.GetType()))
            {
                reference.Instance = Wrapper.Wrap((Service)reference.Instance);
            }

            base.Activate(context, reference);
        }
    }
}
